package vendalenger.debvi;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

import vendalenger.debvi.editors.Welcome_Screen;
import vendalenger.debvi.jfx.DebviFrame;
import vendalenger.port.Command;
import vendalenger.port.Console;
import vendalenger.port.DownloadUtils;

class Loader implements Runnable {

	public static void commandSetup() {
		Command.addCommand(new Command(
				"help",
				"Show help.",
				"How to use this console."
						+ "\nThis whole console is command based. Syntax follows:"
						+ "\n\n ^command arg0,arg1,arg2,arg3,arg4, and so on..."
						+ "\n\nSome commands like '^sum' have return values."
						+ "\nReturn values could be used in Commands with commands"
						+ "\nin them using brackets as so. Think of your BEDMAS, brackets are first."
						+ "\n\n ^sum (^sum 1,4),1 Returns 6"
						+ "\n\nA series of commands could be stored in a .fcis"
						+ "\n(Fluffy Console Interpreted Script)"
						+ "\nFCIS is slow, like lua and js on ie, because it is interpreted"
						+ "\nmeaning it is read line by line by the computer."
						+ "\nAn fcis could be created by a simple text editor."
						+ "\nIn fact, Debvi has an fcis editor built in.") {
			@Override
			public String action(String[] args) {
				// System.out.println(args[0]);
				if (args[0].equalsIgnoreCase("null")) {
					System.out.println("Showing list of commands: ");
					System.out.println("For more details, use help key");
					System.out.println("Key----------------------------");
					for (int i = 0; i < Command.commandList.size(); i++) {
						System.out.println(Command.commandList.get(i).key
								+ " - " + Command.commandList.get(i).help);
					}
					System.out
							.println("Have no clue of what your doing? try \"^help help\"");
				} else {
					System.out.println("Showing long help for command: "
							+ args[0]);
					System.out.println("-------------------------------");
					for (int i = 0; i < Command.commandList.size(); i++) {
						if (commandList.get(i).key.equalsIgnoreCase(args[0])) {
							System.out.println(commandList.get(i).usage);
						}
					}
				}
				return null;
			}
		}, false);

		Command.addCommand(new Command("clr", "Clear the console screen.",
				"Calcium, Lime, and Rust!") {
			@Override
			public String action(String[] args) {
				Console.clear();
				return null;
			}
		}, false);

		Command.addCommand(new Command("gc", "Free memory from JVM", "Free memory from the JVM"
				+ "\nIn java, System.gc(); is called."
				+ "\njavaw will still use as much memory.") {
			@Override
			public String action(String[] args) {
				System.gc();
				return null;
			}
		}, false);

		Command.addCommand(new Command("info", "Show information.", "^info [noprint] "
				+ "\nShow basic information about Debvi"
				+ "\nReturns the version of Debvi. currently: "
				+ Debvi.getDebviVersion() + "\nbool: noprint - Don't print.") {
			@Override
			public String action(String[] args) {
				if (!Boolean.parseBoolean(args[0])) {
					System.out.println("Debvi " + Debvi.getDebviVersion());
					System.out
							.println("Created by Chris/Christopher/Neal Nicdao");
					System.out
							.println("Mr. Shelby, one question... Do you like eggs?");
				}
				return Debvi.getDebviVersion();
			}
		}, false);

		Command.addCommand(new Command("print", "Print a message.", "^print [message] "
				+ "\nwhat else? hello world?") {
			@Override
			public String action(String[] args) {
				System.out.println(args[0]);
				return "";
			}
		}, false);

		Command.addCommand(new Command(
				"title",
				"Set or return the title of the Debvi screen or this.",
				"^title [console,debvi],[return],[title]"
						+ "\ntitle console : Set mode to the title of this Console"
						+ "\ntitle debvi : Set mode to the title of the Debvi screen"
						+ "\nBool: return Return the title of console or debvi"
						+ "\nString: title The title to be set.") {
			@Override
			public String action(String[] args) {
				String re = "";
				if (Boolean.parseBoolean(args[1])) {
					if (args[0].equals("console")) {
						re = Console.consoleWindow.getTitle();
					}
					if (args[0].equals("debvi")) {
						//re = DebviFrame..getTitle();
					}
				} else {
					if (args[0].equals("console")) {
						Console.consoleWindow.setTitle(args[2]);
					}
					if (args[0].equals("debvi")) {
						//DebviFrame.mainWindow.setTitle(args[2]);
					}
				}
				return re;
			}
		}, false);

		Command.addCommand(new Command("sum", "Return the sum of the arguments.", "^add 16,16,32 "
				+ "\nReturns 64.") {
			@Override
			public String action(String[] args) {
				double sum = 0;
				for (String s : args) {
					try {
						sum += Double.parseDouble(s);
					} catch (NumberFormatException e) {
						System.err.println(s + " is not a valid number.");
					}
				}
				System.out.println(sum);
				return String.valueOf(sum);
			}
		}, false);

		Command.addCommand(new Command("sub", "Subtract the arguments from left to right.",
				"^sub 32,64,-5 " + "\nReturns -27.0") {
			@Override
			public String action(String[] args) {
				double sum = 0;
				try {
					sum = Double.parseDouble(args[0]);
					for (int i = 0; i < args.length - 1; i++) {
						sum -= Double.parseDouble(args[i + 1]);
					}
				} catch (NumberFormatException e) {
					System.err.println("Numbers are invalid.");
				}
				System.out.println(sum);
				return String.valueOf(sum);
			}
		}, false);

		Command.addCommand(new Command(
				"open",
				"Open the selected file.",
				"^open [file],[internal]"
						+ "\nFile: file - The path to the file."
						+ "\nBool: internal - If true, open the file with built-in editors."
						+ "\nelse, open the file using system default.") {

			@Override
			public String action(String[] args) {
				File f = new File(args[0]);
				if (Boolean.parseBoolean(args[1])) {
					Debvi.openFile(f);
				} else {
					try {
						Desktop.getDesktop().open(f);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				return null;
			}
		}, false);
		
		Command.addCommand(new Command(
				"ff",
				"File format operations.",
				"^ff [arg0]"
						+ "\n^ff list : Prints the known file formats and their default open operation."
						+ "\n^ff add [.fileformat] [command] [command args].. : Define a file format and how to open it."
						+ "\n    Example: ^ff add,png,^imgv,# : # is the variable for the path to file.") {
			@Override
			public String action(String[] args) {
				if (args[0].equals("list")) {
					System.out.println("Listing known file formats...");
					for (int i = 0; i < Preferences.knownFileFormats.size(); i++) {
						System.out.println(Preferences.knownFileFormats.get(i)
								+ " : "
								+ Preferences.knownFileFormatsCommand.get(i));
					}
				} else if (args[0].equals("add")) {

				} else {
					Command.issue("^help ff");
				}
				return null;
			}
		}, false);
		
		Command.addCommand(new Command(
				"welcome",
				"Open the welcome screen",
				"^welcome"
						+ "\nthats all it is to it.") {

			@Override
			public String action(String[] args) {
				new Welcome_Screen().open(args);
				return null;
			}
		}, false);

		Command.addCommand(new Command("eggs", "Show your eggs.", "Do you like eggs?") {
			@Override
			public String action(String[] args) {
				// The \u2588 character is the full block character.
				System.out
						.println("\u2588\u2588\u2588\u2588  \u2588\u2588\u2588\u2588\u2588   \u2588   \u2588 \u2588\u2588\u2588\u2588\u2588 \u2588   \u2588   \u2588     \u2588\u2588\u2588\u2588\u2588 \u2588 \u2588   \u2588 \u2588\u2588\u2588\u2588\u2588");
				System.out
						.println("\u2588   \u2588 \u2588   \u2588   \u2588   \u2588 \u2588   \u2588 \u2588   \u2588   \u2588     \u2588     \u2588 \u2588  \u2588  \u2588");
				System.out
						.println("\u2588   \u2588 \u2588   \u2588    \u2588 \u2588  \u2588   \u2588 \u2588   \u2588   \u2588     \u2588\u2588\u2588\u2588\u2588 \u2588 \u2588\u2588\u2588   \u2588\u2588\u2588\u2588\u2588");
				System.out
						.println("\u2588   \u2588 \u2588   \u2588     \u2588   \u2588   \u2588 \u2588   \u2588   \u2588     \u2588     \u2588 \u2588  \u2588  \u2588");
				System.out
						.println("\u2588\u2588\u2588\u2588  \u2588\u2588\u2588\u2588\u2588     \u2588   \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588   \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588 \u2588   \u2588 \u2588\u2588\u2588\u2588\u2588");
				System.out.println("");
				System.out
						.println("\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588");
				System.out
						.println("\u2588     \u2588     \u2588     \u2588         \u2588");
				System.out
						.println("\u2588\u2588\u2588\u2588\u2588 \u2588  \u2588\u2588 \u2588  \u2588\u2588 \u2588\u2588\u2588\u2588\u2588    \u2588");
				System.out
						.println("\u2588     \u2588   \u2588 \u2588   \u2588     \u2588   ");
				System.out
						.println("\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588   \u2588");
				return "Eggs";
			}
		}, true);
	}

	@Override
	public void run() {
		System.out.println("Debvi is initializing...");
		System.out.println("Debvi version: " + Debvi.getDebviVersion());
		System.out.println("Detected Operating System: ");
		System.out.println(System.getProperty("os.name"));
		System.out.println("on Directory: ");
		System.out.println(System.getProperty("user.dir"));
		File plugins = new File("Resource/");
		File resources = new File("Resource/");
		if (resources.exists()) {
			System.out.println("Using resources: "
					+ resources.getAbsolutePath());
		} else {
			System.out.println("Retrieving resource files...");
			System.out
					.println("Now downloading http://vendalenger.hostei.com/debvi_release/resource.zip");
			DownloadUtils.downloadFile(
					"http://vendalenger.hostei.com/debvi_release/Resource/resources2.zip",
					"resource.zip");
			System.out.println("unzipping resource.zip to ");
			DownloadUtils.unZip("resource.zip", ".");
		}

		if (plugins.exists()) {
			System.out.println("Using plugins: " + resources.getAbsolutePath());
		} else {
			System.out.println("Plugins are not yet implemented in this version.");
			// System.out.println("Retrieving resource files...");
			// Vutils.downloadFile(
			// 		"http://vendalenger.hostei.com/debvi_release/Resource/resources2.zip",
			// 		"resource.zip");
			// System.out.println("unzipping resource.zip to ");
			// Vutils.unZip("resource.zip", ".");
		}

		Preferences.setup();

		//Console.showConsole();

		commandSetup();
		Debvi.setup();
	}
}

public class Main {

	public static String[] args;
	public static JProgressBar loadingBar;
	public static JFrame loadingScreen;

	/**
	 * The start of every Java application. The main method is also used in
	 * other languages such as C++ :D
	 */
	public static void main(String[] args0) throws IOException {
		args = args0;
		Console.initConsole(460, 320); // Initialize the console
		Console.showConsole(); // Then show it
		System.out.println("Hello World is very original");
		loadingScreen = new JFrame();
		loadingScreen.setLayout(new BorderLayout());
		loadingScreen.setUndecorated(true);
		loadingScreen.setIconImage(Console.consoleWindow.getIconImage());
		JLabel image = new JLabel(new ImageIcon(
				Main.class.getResource("Debvi_loading.png")));
		loadingBar = new JProgressBar();
		loadingBar.setBorder(null);
		loadingBar.setBackground(Color.black);
		loadingBar.setForeground(new Color(93, 230, 0));
		loadingBar.setIndeterminate(true);
		loadingScreen.add(image, BorderLayout.CENTER);
		loadingScreen.add(loadingBar, BorderLayout.SOUTH);
		loadingScreen.pack();
		loadingScreen.setLocationRelativeTo(null);
		loadingScreen.setVisible(true);
		Thread l = new Thread(new Loader());
		l.start();
	}
}
